{/* Copyright 2020 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License. */}

import {Layout} from '@react-spectrum/docs';
export default Layout;

import docs from 'docs:@react-spectrum/form';
import {HeaderInfo, PropTable, PageDescription} from '@react-spectrum/docs';
import packageData from '@react-spectrum/form/package.json';

```jsx import
 import {Checkbox} from '@react-spectrum/checkbox';
 import {Form} from '@react-spectrum/form';
 import {Radio, RadioGroup} from '@react-spectrum/radio';
 import {TextField} from '@react-spectrum/textfield';
 ```

---
category: Forms
---

# Form

<PageDescription>{docs.exports.Form.description}</PageDescription>

<HeaderInfo
 packageData={packageData}
 componentNames={['Form']}
 since="3.0.0" />

## Example

```tsx example
<Form maxWidth="size-3600">
  <TextField label="Email" />
  <TextField label="Password" />
  <Checkbox>Remember me</Checkbox>
</Form>
```

## Content

Form accepts one or more children to render as its form elements. Label alignment, positioning, and other [properties](#visual-options)
are set on the Form itself and propagated to its children to generate a cohesive design. To override these top level Form props on individual children,
set them directly on the child instead.

```tsx example
<Form maxWidth="size-3600" isRequired necessityIndicator="label">
  <TextField label="Name" />
  <TextField label="Email" />
  <TextField label="Address" isRequired={false} />
</Form>
```

## Labeling

### Accessibility

A label should be provided to the Form by adding either the `aria-label` or `aria-labelledby` prop, so that the element will be identified to assistive
technology as a form landmark region to which assistive technology can navigate.

```tsx example
<h3 id="label-3">Personal Information</h3>
<Form maxWidth="size-3600" aria-labelledby="label-3">
  <TextField label="First Name" />
  <TextField label="Last Name" />
  <RadioGroup label="Favorite pet">
    <Radio value="dogs">Dogs</Radio>
    <Radio value="cats">Cats</Radio>
    <Radio value="dragons">Dragons</Radio>
  </RadioGroup>
</Form>
```

## Validation

React Spectrum supports native HTML constraint validation with customizable UI, custom validation functions, realtime validation, and integration with server-side validation errors. The `Form` component facilitates server-side validation by providing error messages to the fields within it.

To provide validation errors, the `validationErrors` prop should be set to an object that maps each field's `name` prop to a string or array of strings representing one or more errors. These are displayed to the user as soon as the `validationErrors` prop is set, and cleared after the user modifies each field's value.

```tsx example
<Form validationErrors={{username: 'Sorry, this username is taken.'}} maxWidth="size-3000">
  <TextField label="Username" name="username" />
</Form>
```

See the [Forms](forms.html) guide to learn more about form validation in React Spectrum, including client-side validation, and integration with other frameworks and libraries.

### Validation behavior

By default, validation errors are displayed to the user in realtime as the value is edited, and do not block form submission. To enable native HTML form validation and prevent form submission when fields are invalid, set the `validationBehavior` prop to `"native"`.

```tsx example
import {ButtonGroup, Button} from '@adobe/react-spectrum';

<Form validationBehavior="native" maxWidth="size-3000">
  <TextField label="Email" name="email" type="email" isRequired />
  <ButtonGroup>
    <Button type="submit" variant="primary">Submit</Button>
    <Button type="reset" variant="secondary">Reset</Button>
  </ButtonGroup>
</Form>
```

### Focus management

By default, after a user submits a form with validation errors, the first invalid field will be focused. You can prevent this by calling `preventDefault` during the `onInvalid` event, and move focus yourself.

This example shows how to move focus to an [InlineAlert](InlineAlert.html) using the `autoFocus` prop when displaying validation errors at the top of a form.

```tsx example
import {InlineAlert, Heading, Content} from '@adobe/react-spectrum';

function Example() {
  let [isInvalid, setInvalid] = React.useState(false);

  return (
    <Form
      validationBehavior="native"
      /*- begin highlight -*/
      onInvalid={e => {
        e.preventDefault();
        setInvalid(true);
      }}
      /*- end highlight -*/
      onSubmit={e => {
        e.preventDefault();
        setInvalid(false);
      }}
      onReset={() => setInvalid(false)}
      maxWidth="size-3600">
      {isInvalid &&
        /*- begin highlight -*/
        <InlineAlert variant="negative" autoFocus>
        {/*- end highlight -*/}
          <Heading>Unable to submit</Heading>
          <Content>
            Please fix the validation errors below, and re-submit the form.
          </Content>
        </InlineAlert>
      }
      <TextField label="First Name" isRequired />
      <TextField label="Last Name" isRequired />
      <ButtonGroup>
        <Button type="submit" variant="primary">Submit</Button>
        <Button type="reset" variant="secondary">Reset</Button>
      </ButtonGroup>
    </Form>
  );
}
```

## Props

<PropTable component={docs.exports.Form} links={docs.links} />

## Visual options

### Label position and alignment
Top label position, start label alignment
```tsx example
<Form
  labelPosition="top"
  labelAlign="start"
  aria-label="Top position, start alignment example"
  maxWidth="size-3600">
  <TextField label="Name" />
  <RadioGroup label="Favorite pet">
    <Radio value="dogs">Dogs</Radio>
    <Radio value="cats">Cats</Radio>
  </RadioGroup>
</Form>
```
Side label position, start label alignment
```tsx example
<Form
  labelPosition="side"
  labelAlign="start"
  aria-label="Side position, start alignment example"
  maxWidth="size-3600">
  <TextField label="Name" />
  <RadioGroup label="Favorite pet">
    <Radio value="dogs">Dogs</Radio>
    <Radio value="cats">Cats</Radio>
  </RadioGroup>
</Form>
```
Side label position, end label alignment
```tsx example
<Form
  labelPosition="side"
  labelAlign="end"
  aria-label="Side position, end alignment example"
  maxWidth="size-3600">
  <TextField label="Name" />
  <RadioGroup label="Favorite pet">
    <Radio value="dogs">Dogs</Radio>
    <Radio value="cats">Cats</Radio>
  </RadioGroup>
</Form>
```

### Quiet

```tsx example
<Form
  isQuiet
  aria-label="Quiet example"
  maxWidth="size-3600">
  <TextField label="Name" />
  <TextField label="Address" />
</Form>
```

### Emphasized

```tsx example
<Form
  isEmphasized
  aria-label="Emphasized example"
  maxWidth="size-3600">
  <TextField label="Name"/>
  <RadioGroup label="Favorite pet" defaultValue="dogs">
    <Radio value="dogs">Dogs</Radio>
    <Radio value="cats">Cats</Radio>
  </RadioGroup>
</Form>
```

### Disabled

```tsx example
<Form
  isDisabled
  aria-label="Disabled example"
  maxWidth="size-3600">
  <TextField label="Name" />
  <RadioGroup label="Favorite pet">
    <Radio value="dogs">Dogs</Radio>
    <Radio value="cats">Cats</Radio>
  </RadioGroup>
</Form>
```

### Required and necessity indicator

Optional label
```tsx example
<Form
  necessityIndicator="label"
  aria-label="Optional with label example"
  maxWidth="size-3600">
  <TextField label="Name" />
  <RadioGroup label="Favorite pet">
    <Radio value="dogs">Dogs</Radio>
    <Radio value="cats">Cats</Radio>
  </RadioGroup>
</Form>
```
Required label
```tsx example
<Form
  isRequired
  necessityIndicator="label"
  aria-label="Required with label example"
  maxWidth="size-3600">
  <TextField label="Name" />
  <RadioGroup label="Favorite pet">
    <Radio value="dogs">Dogs</Radio>
    <Radio value="cats">Cats</Radio>
  </RadioGroup>
</Form>
```
Required with asterisk
```tsx example
<Form
  isRequired
  necessityIndicator="icon"
  aria-label="Required with asterisk example"
  maxWidth="size-3600">
  <TextField label="Name" />
  <RadioGroup label="Favorite pet">
    <Radio value="dogs">Dogs</Radio>
    <Radio value="cats">Cats</Radio>
  </RadioGroup>
</Form>
```

### Read only

```tsx example
<Form
  isReadOnly
  aria-label="isReadOnly example"
  maxWidth="size-3600">
  <TextField label="Name" value="John Smith" />
  <RadioGroup label="Favorite pet">
    <Radio value="dogs">Dogs</Radio>
    <Radio value="cats">Cats</Radio>
  </RadioGroup>
</Form>
```

### Validation state

```tsx example
<Form
  validationState="invalid"
  aria-label="Invalid validationState example"
  maxWidth="size-3600"
  marginBottom="size-300">
  <TextField label="Name" />
  <RadioGroup label="Favorite pet">
    <Radio value="dogs">Dogs</Radio>
    <Radio value="cats">Cats</Radio>
  </RadioGroup>
</Form>
```
```tsx example
<Form
  validationState="valid"
  aria-label="Valid validationState example"
  maxWidth="size-3600">
  <TextField label="Name" />
  <RadioGroup label="Favorite pet">
    <Radio value="dogs">Dogs</Radio>
    <Radio value="cats">Cats</Radio>
  </RadioGroup>
</Form>
```
